package com.sz.common.pay.pingan.util;

import com.sz.common.pay.pingan.core.client.Connection;

import java.io.IOException;
import java.net.*;
import java.util.Enumeration;

/**
 * Function: 测试配置的链接是否有效 <br>
 * Author: siqishangshu <br>
 * Date: 2017-11-07 13:06:00
 */
public class ConnectUtil {

    private static final int TIMEOUT = 5000;

    public static boolean reachableConnection(Connection connection){
        String retIP = null;
        Enumeration<NetworkInterface> netInterfaces;
        try{
        InetAddress remoteAddr = InetAddress.getByName(connection.getHost());
            netInterfaces = NetworkInterface.getNetworkInterfaces();
            while(netInterfaces.hasMoreElements()) {
                NetworkInterface ni = netInterfaces.nextElement();
                Enumeration<InetAddress> localAddrs = ni.getInetAddresses();
                while(localAddrs.hasMoreElements()){
                    InetAddress localAddr = localAddrs.nextElement();
                    if(isReachable(localAddr, remoteAddr, connection.getPort(), TIMEOUT)){
                        retIP = localAddr.getHostAddress();
                        break;
                    }
                }
            }
        } catch(Exception e) {
        }
        return retIP != null;
    }

   private static boolean isReachable(InetAddress localInetAddr, InetAddress remoteInetAddr, int port, int timeout) {
        boolean isReachable = false;
        Socket socket = null;
        try{
            socket = new Socket();
            SocketAddress localSocketAddr = new InetSocketAddress(localInetAddr, 0);
            socket.bind(localSocketAddr);
            InetSocketAddress endpointSocketAddr = new InetSocketAddress(remoteInetAddr, port);
            socket.connect(endpointSocketAddr, timeout);
            isReachable = true;
        } catch(IOException e) {

        } finally{
            if(socket != null) {
                try{
                    socket.close();
                } catch(IOException e) {
                }
            }
        }
        return isReachable;
    }
}
